package com.rybbaby.tss.platform.sysAdminUser.service.imp;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.rybbaby.tss.core.redis.RedisClient;
import com.rybbaby.tss.core.utils.JSONUtil;
import com.rybbaby.tss.core.utils.SpringApplicationContextUtil;
import com.rybbaby.tss.core.utils.StringUtils;
import com.rybbaby.tss.core.web.service.imp.BaseServiceImp;
import com.rybbaby.tss.platform.initializer.HandlePermissionsInitializer;
import com.rybbaby.tss.platform.sysAdminUser.dao.ISysAdminUserDao;
import com.rybbaby.tss.platform.sysAdminUser.entity.SysAdminUser;
import com.rybbaby.tss.platform.sysAdminUser.service.ISysAdminUserService;
import com.rybbaby.tss.platform.sysAdminUserJoinSysMenuPermissions.entity.SysAdminUserJoinSysMenuPermissions;
import com.rybbaby.tss.platform.sysAdminUserJoinSysMenuPermissions.service.ISysAdminUserJoinSysMenuPermissionsService;
import com.rybbaby.tss.platform.sysFileUseLog.service.ISysFileUseLogService;
import com.rybbaby.tss.platform.sysFiles.service.ISysFilesService;
import com.rybbaby.tss.platform.sysRoleJoinSysMenuPermissions.entity.SysRoleJoinSysMenuPermissions;
import com.rybbaby.tss.platform.sysRoleJoinSysMenuPermissions.service.ISysRoleJoinSysMenuPermissionsService;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Table;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author 谢进伟
 * @description 管理员基本信息数据库操作服务实现
 * @createDate 2016-11-22 下午1:36:42
 */
@Service
@Transactional
public class SysAdminUserServiceImp extends BaseServiceImp<SysAdminUser> implements ISysAdminUserService {

	@Autowired
	private ISysFilesService sysFilesService;
	@Autowired
	private ISysFileUseLogService sysFileUseLogService;
	@Autowired
	private ISysAdminUserJoinSysMenuPermissionsService sysAdminUserJoinSysMenuPermissionsService;
	@Autowired
	private ISysRoleJoinSysMenuPermissionsService sysRoleJoinSysMenuPermissionsService;
	@Autowired
	private ISysAdminUserDao dao;

	/**
	 * ehcache缓存管理
	 **/
	private static CacheManager ehcacheManager;
	/**
	 * 在线用户操作权限分配缓存
	 **/
	private static Cache onlineUserPermissionAllotEhcache;

	static {
		ehcacheManager = SpringApplicationContextUtil.getContext().getBean(CacheManager.class);
		onlineUserPermissionAllotEhcache = ehcacheManager.getCache("onlineUserPermissionAllotEhcache");
	}

	@Override
	public Serializable save(SysAdminUser entity, String sessionId, String loginUserId, String... fileRelevances) throws Exception {
		if(entity == null) {
			return null;
		}
		Serializable businessId = save(entity);
		if(businessId != null) {
			if(fileRelevances != null && fileRelevances.length > 0) {
				Table table = SysAdminUser.class.getAnnotation(Table.class);
				String businessTableName = table.name();
				for(String fileRelevance : fileRelevances) {
					if(StringUtils.isNotBlank(fileRelevance)) {
						if(!fileRelevance.contains("=>")) {
							continue;
						}
						String[] fileReleVanceInfo = fileRelevance.split("=>");
						String groupName = fileReleVanceInfo[0];
						String fieldName = fileReleVanceInfo[1];
						if(!sysFilesService.useFile(businessTableName, "id", businessId, fieldName, groupName, sessionId, loginUserId, null)) {
							throw new Exception("使用文件失败!");
						}
					}
				}
			}
		}
		return businessId;
	}

	@Override
	public void updateEntitiy(SysAdminUser entity, String sessionId, String loginUserId, String delteFileIds, String... fileRelevances) throws Exception {
		if(entity != null && entity.getId() != null) {
			saveOrUpdate(entity);
			Class<? extends SysAdminUser> cls = entity.getClass();
			if(fileRelevances != null && fileRelevances.length > 0) {
				Table table = SysAdminUser.class.getAnnotation(Table.class);
				String businessTableName = table.name();
				for(String fileRelevance : fileRelevances) {
					if(StringUtils.isNotBlank(fileRelevance)) {
						if(!fileRelevance.contains("=>")) {
							continue;
						}
						String[] fileReleVanceInfo = fileRelevance.split("=>");
						String groupName = fileReleVanceInfo[0];
						String fieldName = fileReleVanceInfo[1];
						Field declaredField = cls.getDeclaredField(fieldName);
						declaredField.setAccessible(true);
						Object oldValue = declaredField.get(entity);
						if(!sysFilesService.updateUsedFile(businessTableName, "id", entity.getId(), fieldName, groupName, sessionId, loginUserId, delteFileIds, oldValue + "")) {
							throw new Exception("使用文件失败!");
						}
					}
				}
			}
		}
	}

	@Override
	public void onLine(SysAdminUser entity, String sessionId) {
		cacheUserPermissionAllot(entity);
		// 修改用户为在线状态
		entity.setIsOnline(1);
		entity.setOnlineSessionId(sessionId);
		this.updateEntitiy(entity);
	}

	@Override
	public void offLine(SysAdminUser entity) {
		if(entity != null) {
			removeCacheUserPermissionAllot(entity);
			entity.setIsOnline(0);
			entity.setOnlineSessionId(null);
			this.updateEntitiy(entity);
		}
	}

	@Override
	public Integer updateIsForbidden(String targetDateId,Boolean isForbidden) {
		return dao.updateIsForbidden(targetDateId,isForbidden);
	}

	/**
	 * 缓存权限分配信息
	 *
	 * @param entity 登录用户对象
	 */
	private void cacheUserPermissionAllot(SysAdminUser entity) {
		boolean redisIsCanUse = RedisClient.isCanUse();
		if(onlineUserPermissionAllotEhcache == null && !redisIsCanUse) {
			return;
		}
		String loginUserId = entity.getId();
		// 登录用户私有菜单权限
		List<SysAdminUserJoinSysMenuPermissions> sajsmpList = this.sysAdminUserJoinSysMenuPermissionsService.findByProperty("adminUserId", loginUserId);
		String privatePermissionCachekey = loginUserId + HandlePermissionsInitializer.getCacheUserPermissionAllotSuffix();
		if(!redisIsCanUse) {
			Element userPermissionAllot = new Element(privatePermissionCachekey, sajsmpList);
			onlineUserPermissionAllotEhcache.put(userPermissionAllot);// 缓存私有权限分配
		} else {
			try {
				List<SysAdminUserJoinSysMenuPermissions> sajsmpList_new = new ArrayList<SysAdminUserJoinSysMenuPermissions>();
				sajsmpList.parallelStream().forEach((SysAdminUserJoinSysMenuPermissions saujsmp) -> {
					SysAdminUserJoinSysMenuPermissions saujsmp_new = new SysAdminUserJoinSysMenuPermissions();
					BeanUtils.copyProperties(saujsmp, saujsmp_new, "menuPermission");
					sajsmpList_new.add(saujsmp_new);
				});
				RedisClient.del(privatePermissionCachekey);
				RedisClient.set(privatePermissionCachekey, JSONUtil.toJsonStr(sajsmpList_new));
			} catch (JsonProcessingException e) {
				e.printStackTrace();
			}
		}
		// 登录用户拥有的角色所对应的菜单权限
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT id, roleId, menuPermissionsId, createTime, createUserId, weight, version FROM sys_role_join_sys_menu_permissions");
		sql.append(" WHERE roleId IN(SELECT roleId FROM sys_admin_user_join_sys_role WHERE adminUserId=?)");
		List<SysRoleJoinSysMenuPermissions> srjsmpList;
		try {
			srjsmpList = this.sysRoleJoinSysMenuPermissionsService.findListBySql(sql.toString(), new Object[]{loginUserId});
			String rolePermissionCacheKey = loginUserId + HandlePermissionsInitializer.getCacheRolePermissionAllotSuffix();
			if(!redisIsCanUse) {
				Element rolePermissionAllot = new Element(rolePermissionCacheKey, srjsmpList);
				onlineUserPermissionAllotEhcache.put(rolePermissionAllot);// 缓存角色权限分配
			} else {
				RedisClient.del(rolePermissionCacheKey);
				RedisClient.set(rolePermissionCacheKey, JSONUtil.toJsonStr(srjsmpList));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 移除缓存的权限分配信息
	 *
	 * @param entity 登录用户对象
	 */
	private void removeCacheUserPermissionAllot(SysAdminUser entity) {
		boolean redisIsCanUse = RedisClient.isCanUse();
		if(onlineUserPermissionAllotEhcache == null && !redisIsCanUse) {
			return;
		}
		String loginUserId = entity.getId();
		String privatePermissionCachekey = loginUserId + HandlePermissionsInitializer.getCacheUserPermissionAllotSuffix();
		String rolePermissionCacheKey = loginUserId + HandlePermissionsInitializer.getCacheRolePermissionAllotSuffix();
		if(!redisIsCanUse) {
			onlineUserPermissionAllotEhcache.remove(privatePermissionCachekey);
			onlineUserPermissionAllotEhcache.remove(rolePermissionCacheKey);
		} else {
			RedisClient.del(privatePermissionCachekey, rolePermissionCacheKey);
		}
	}

	/**
	 * 获取所有数据集合
	 * */
	@Override
	public List<SysAdminUser> getAllList() {
		return dao.getAllList();
	}

	/**
	 * 根据ID集合获取该集合
	 * */
	@Override
	public List<SysAdminUser> findListByIds(List<String> ids) {
		return dao.findListByIds(ids);
	}

	@Override
	public List<SysAdminUser> getPostListByDuty(Integer duty,String schoolId) throws Exception {
		return dao.getPostListByDuty(duty,schoolId);
	}

	@Override
	public List<SysAdminUser> findByUserNamePassWord(String userName, String password) throws Exception {
		return dao.findByUserNamePassWord(userName,password);
	}

	@Override
	public List<SysAdminUser> findByuserName(String userName) throws Exception {
		return dao.findByuserName(userName);
	}

	@Override
	public Map<String, Object> findSchoolCode(String adminUserId) {
		return dao.findSchoolCode(adminUserId);
	}

}
